<!--<!DOCTYPE html>-->
<!--<html lang="zh-CN">-->
<!--<head>-->
<!--    <meta charset="UTF-8">-->
<!--    <meta name="viewport" content="width=device-width, initial-scale=1.0">-->
<!--    <title>网园智能Agent</title>-->
<!--    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">-->
<!--    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">-->
<!--    <script src="https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.min.js"></script>-->
<!--    <style>-->
<!--        body {-->
<!--            font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;-->
<!--        }-->

<!--        /* 滚动条样式 */-->
<!--        ::-webkit-scrollbar {-->
<!--            width: 6px;-->
<!--        }-->

<!--        ::-webkit-scrollbar-track {-->
<!--            background: #f1f1f1;-->
<!--        }-->

<!--        ::-webkit-scrollbar-thumb {-->
<!--            background: #c1c1c1;-->
<!--            border-radius: 3px;-->
<!--        }-->

<!--        ::-webkit-scrollbar-thumb:hover {-->
<!--            background: #a8a8a8;-->
<!--        }-->

<!--        /* 输入框自适应高度 */-->
<!--        textarea {-->
<!--            min-height: 44px;-->
<!--            max-height: 200px;-->
<!--            transition: height 0.2s;-->
<!--        }-->

<!--        /* 加载动画 */-->
<!--        @keyframes pulse {-->
<!--            0%, 100% {-->
<!--                opacity: 0.5;-->
<!--            }-->
<!--            50% {-->
<!--                opacity: 1;-->
<!--            }-->
<!--        }-->

<!--        .animate-pulse {-->
<!--            animation: pulse 1.5s infinite;-->
<!--        }-->

<!--        .delay-100 {-->
<!--            animation-delay: 0.1s;-->
<!--        }-->

<!--        .delay-200 {-->
<!--            animation-delay: 0.2s;-->
<!--        }-->

<!--        /* 打字机效果 */-->
<!--        .typing-cursor::after {-->
<!--            content: "|";-->
<!--            animation: blink 1s step-end infinite;-->
<!--        }-->

<!--        @keyframes blink {-->
<!--            from, to {-->
<!--                opacity: 1;-->
<!--            }-->
<!--            50% {-->
<!--                opacity: 0;-->
<!--            }-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--<div id="app" class="flex flex-col h-screen bg-gray-50">-->
<!--    &lt;!&ndash; 顶部导航栏 &ndash;&gt;-->
<!--    <header class="bg-white border-b border-gray-200 py-4 px-6 flex items-center justify-between">-->
<!--        <div class="flex items-center">-->
<!--            <div class="text-xl font-bold text-blue-600">网园智能Agent</div>-->
<!--        </div>-->
<!--        <div class="flex items-center space-x-3">-->
<!--            <button class="ml-2 w-10 h-10 rounded-full bg-green-500 hover:bg-green-600 text-white shadow-sm transition">-->
<!--                <i class="fas fa-plus"></i>-->
<!--            </button>-->
<!--            <button @click="toggleDarkMode" class="p-2 rounded-full hover:bg-gray-100">-->
<!--                <i :class="darkMode ? 'fas fa-moon text-gray-600' : 'fas fa-sun text-gray-600'"></i>-->
<!--            </button>-->
<!--        </div>-->
<!--    </header>-->

<!--    &lt;!&ndash; 聊天内容区域 &ndash;&gt;-->
<!--    <main class="flex-1 overflow-y-auto px-4 py-6 space-y-6 transition-colors duration-300"-->
<!--          ref="chatContainer"-->
<!--          :class="{ 'bg-gray-900': darkMode, 'bg-gray-50': !darkMode }">-->
<!--        <div v-for="(message, index) in messages" :key="index" class="max-w-3xl mx-auto">-->
<!--            <div :class="['flex', message.role === 'user' ? 'justify-end' : 'justify-start']">-->
<!--                <div :class="['flex items-start space-x-3', message.role === 'user' ? 'flex-row-reverse space-x-reverse' : '']">-->
<!--                    <div :class="['w-8 h-8 rounded-full flex items-center justify-center',-->
<!--                                    message.role === 'user' ? 'bg-blue-100 text-blue-600' : 'bg-green-100 text-green-600',-->
<!--                                    darkMode && message.role === 'assistant' ? 'bg-gray-700 text-green-400' : '']">-->
<!--                        &lt;!&ndash;                        <i :class="message.role === 'user' ? 'fas fa-user' : 'fas fa-robot'"></i>&ndash;&gt;-->
<!--                        <img :src="message.role === 'user' ?-->
<!--                         '' :-->
<!--                         ''">-->
<!--                    </div>-->
<!--                    <div :class="['p-4 rounded-2xl max-w-xl text-sm leading-relaxed shadow-sm',-->
<!--                                    message.role === 'user'-->
<!--                                        ? 'bg-blue-500 text-white'-->
<!--                                        : darkMode-->
<!--                                            ? 'bg-gray-700 text-gray-100 border-gray-600'-->
<!--                                            : 'bg-white shadow border border-gray-100']">-->
<!--                        <div v-if="message.role === 'assistant' && message.isLoading" class="flex space-x-2">-->
<!--                            <div :class="['w-2 h-2 rounded-full', darkMode ? 'bg-gray-400' : 'bg-gray-300', 'animate-pulse']"></div>-->
<!--                            <div :class="['w-2 h-2 rounded-full', darkMode ? 'bg-gray-400' : 'bg-gray-300', 'animate-pulse delay-100']"></div>-->
<!--                            <div :class="['w-2 h-2 rounded-full', darkMode ? 'bg-gray-400' : 'bg-gray-300', 'animate-pulse delay-200']"></div>-->
<!--                        </div>-->
<!--                        <div v-else class="whitespace-pre-wrap">-->
<!--                                <span v-for="(char, charIndex) in message.content" :key="charIndex"-->
<!--                                      :class="{'opacity-0': charIndex >= message.visibleChars, 'fade-in': charIndex < message.visibleChars}">-->
<!--                                    {{ char }}-->
<!--                                </span>-->
<!--                            <span v-if="message.isStreaming" class="typing-cursor"></span>-->
<!--                        </div>-->
<!--                    </div>-->
<!--                </div>-->
<!--            </div>-->
<!--        </div>-->
<!--    </main>-->

<!--    &lt;!&ndash; 输入框区域 &ndash;&gt;-->
<!--    <footer :class="['border-t p-4', darkMode ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200']">-->
<!--        <div class="max-w-3xl mx-auto relative">-->
<!--            <div class="flex items-center">-->
<!--                    <textarea-->
<!--                            v-model="userInput"-->
<!--                            @keydown.enter.exact.prevent="sendMessage"-->
<!--                            @keydown.ctrl.enter.exact.prevent="sendMessage"-->
<!--                            @keydown.esc.exact="stopResponse"-->
<!--                            placeholder="输入您的问题..."-->
<!--                            :class="['flex-1 border rounded-xl py-3 px-4 pr-12 focus:outline-none focus:ring-2 resize-none',-->
<!--    darkMode-->
<!--        ? 'bg-gray-800 border-gray-600 text-white focus:ring-blue-400 placeholder-gray-400'-->
<!--        : 'bg-white border-gray-200 focus:ring-blue-500 shadow-sm']"-->

<!--                            rows="1"-->
<!--                            ref="textarea"-->
<!--                            @input="adjustTextareaHeight"-->
<!--                    ></textarea>-->
<!--                &lt;!&ndash; 新建会话按钮 &ndash;&gt;-->

<!--                <button-->
<!--                        @click="isLoading ? stopResponse() : sendMessage()"-->
<!--                        :disabled="!userInput.trim() && !isLoading"-->
<!--                        :class="['ml-2 w-10 h-10 rounded-full flex items-center justify-center shadow-sm transition',-->
<!--                                isLoading-->
<!--                                    ? 'bg-red-500 hover:bg-red-600 text-white'-->
<!--                                    : 'bg-blue-500 hover:bg-blue-600 text-white',-->
<!--                                'disabled:opacity-50 disabled:cursor-not-allowed']"-->
<!--                >-->
<!--                    <i :class="isLoading ? 'fas fa-stop' : 'fas fa-paper-plane'"></i>-->
<!--                </button>-->
<!--            </div>-->
<!--        </div>-->
<!--    </footer>-->
<!--</div>-->

<!--<script>-->
<!--    const {createApp, ref, nextTick, onMounted, watch} = Vue;-->

<!--    createApp({-->
<!--        setup() {-->
<!--            const messages = ref([]);-->
<!--            const userInput = ref('');-->
<!--            const isLoading = ref(false);-->
<!--            const chatContainer = ref(null);-->
<!--            const textarea = ref(null);-->
<!--            const darkMode = ref(false);-->
<!--            const welcomeText = ref('')-->

<!--            const memoryId = ref(Date.now().toString());-->
<!--            let controller = null;-->
<!--            let typingInterval = null;-->
<!--            let currentTypingIndex = 0;-->

<!--            // 调整文本区域高度-->
<!--            const adjustTextareaHeight = () => {-->
<!--                const textareaEl = textarea.value;-->
<!--                textareaEl.style.height = 'auto';-->
<!--                textareaEl.style.height = `${Math.min(textareaEl.scrollHeight, 200)}px`;-->
<!--            };-->

<!--            // 滚动到底部-->
<!--            const scrollToBottom = () => {-->
<!--                nextTick(() => {-->
<!--                    if (chatContainer.value) {-->
<!--                        chatContainer.value.scrollTop = chatContainer.value.scrollHeight;-->
<!--                    }-->
<!--                });-->
<!--            };-->

<!--            // 切换暗黑模式-->
<!--            const toggleDarkMode = () => {-->
<!--                darkMode.value = !darkMode.value;-->
<!--                localStorage.setItem('darkMode', darkMode.value);-->
<!--            };-->

<!--            // 获取欢迎语-->
<!--            const fetchWelcomeMessage = async () => {-->
<!--                try {-->
<!--                    const res = await fetch("/admin/agent/welcomeMsg");-->
<!--                    const result = await res.json();-->
<!--                    if (result.code === 200) {-->
<!--                        return result.data;-->
<!--                    } else {-->
<!--                        return "你好！我是网园资讯工作室的智能客服，请问有什么能帮到您？";-->
<!--                    }-->
<!--                } catch (error) {-->
<!--                    console.error("获取欢迎语失败:", error);-->
<!--                    return "你好！我是网园资讯工作室的智能客服，请问有什么能帮到您？";-->
<!--                }-->
<!--            };-->

<!--            // 新建会话-->
<!--            const startNewConversation = async () => {-->
<!--                // 清空聊天记录-->
<!--                messages.value = [];-->

<!--                // 生成新的 memoryId-->
<!--                memoryId.value = Date.now().toString();-->

<!--                welcomeText.value = await fetchWelcomeMessage();-->

<!--                // 添加欢迎消息-->
<!--                messages.value.push({-->
<!--                    role: 'assistant',-->
<!--                    content: welcomeText,-->
<!--                    isLoading: false,-->
<!--                    visibleChars: welcomeText.length,-->
<!--                    isStreaming: false-->
<!--                });-->

<!--                // 滚动到底部-->
<!--                scrollToBottom();-->

<!--                // 聚焦输入框-->
<!--                nextTick(() => {-->
<!--                    textarea.value.focus();-->
<!--                });-->
<!--            };-->

<!--            // 模拟逐字打印效果-->
<!--            const startTypingEffect = (messageIndex) => {-->
<!--                const message = messages.value[messageIndex];-->
<!--                if (!message || message.visibleChars >= message.content.length) {-->
<!--                    clearInterval(typingInterval);-->
<!--                    typingInterval = null;-->
<!--                    messages.value[messageIndex].isStreaming = false;-->
<!--                    return;-->
<!--                }-->

<!--                messages.value[messageIndex].visibleChars++;-->
<!--                scrollToBottom();-->
<!--            };-->

<!--            // 发送消息-->
<!--            const sendMessage = async () => {-->
<!--                if (!userInput.value.trim() || isLoading.value) return;-->

<!--                // 中止之前的请求-->
<!--                if (controller) {-->
<!--                    controller.abort();-->
<!--                }-->
<!--                controller = new AbortController();-->

<!--                const userMessage = {-->
<!--                    role: 'user',-->
<!--                    content: userInput.value.trim(),-->
<!--                    isLoading: false,-->
<!--                    visibleChars: userInput.value.trim().length,-->
<!--                    isStreaming: false-->
<!--                };-->

<!--                messages.value.push(userMessage);-->

<!--                const assistantMessage = {-->
<!--                    role: 'assistant',-->
<!--                    content: '',-->
<!--                    isLoading: true,-->
<!--                    visibleChars: 0,-->
<!--                    isStreaming: true-->
<!--                };-->

<!--                messages.value.push(assistantMessage);-->

<!--                userInput.value = '';-->
<!--                adjustTextareaHeight();-->
<!--                scrollToBottom();-->

<!--                isLoading.value = true;-->

<!--                try {-->
<!--                    const response = await fetch(`/chat?message=${encodeURIComponent(userMessage.content)}&memoryId=${memoryId.value}`, {-->
<!--                        signal: controller.signal-->
<!--                    });-->

<!--                    if (!response.ok) {-->
<!--                        throw new Error(`HTTP error! status: ${response.status}`);-->
<!--                    }-->

<!--                    const reader = response.body.getReader();-->
<!--                    const decoder = new TextDecoder('utf-8');-->
<!--                    let buffer = '';-->
<!--                    let messageIndex = messages.value.length - 1;-->

<!--                    // 先清除之前的打字效果-->
<!--                    if (typingInterval) {-->
<!--                        clearInterval(typingInterval);-->
<!--                        typingInterval = null;-->
<!--                    }-->

<!--                    // 开始流式处理-->
<!--                    while (true) {-->
<!--                        const {done, value} = await reader.read();-->
<!--                        if (done) break;-->

<!--                        const chunk = decoder.decode(value, {stream: true});-->
<!--                        buffer += chunk;-->

<!--                        // 直接更新内容-->
<!--                        messages.value[messageIndex].content = buffer;-->
<!--                        messages.value[messageIndex].isLoading = false;-->

<!--                        // 启动打字效果-->
<!--                        if (!typingInterval) {-->
<!--                            typingInterval = setInterval(() => {-->
<!--                                startTypingEffect(messageIndex);-->
<!--                            }, 50); // 调整这个值可以改变打字速度-->
<!--                        }-->

<!--                        scrollToBottom();-->
<!--                    }-->

<!--                } catch (error) {-->
<!--                    if (error.name === 'AbortError') {-->
<!--                        console.log('请求被用户中止');-->
<!--                    } else {-->
<!--                        console.error('请求出错:', error);-->
<!--                        const lastMessage = messages.value[messages.value.length - 1];-->
<!--                        lastMessage.content = '抱歉，请求过程中出现错误: ' + error.message;-->
<!--                        lastMessage.visibleChars = lastMessage.content.length;-->
<!--                    }-->
<!--                } finally {-->
<!--                    const lastMessage = messages.value[messages.value.length - 1];-->
<!--                    lastMessage.isLoading = false;-->
<!--                    lastMessage.isStreaming = false;-->

<!--                    // 确保所有字符都可见-->
<!--                    if (lastMessage.visibleChars < lastMessage.content.length) {-->
<!--                        lastMessage.visibleChars = lastMessage.content.length;-->
<!--                    }-->

<!--                    isLoading.value = false;-->
<!--                    controller = null;-->

<!--                    if (typingInterval) {-->
<!--                        clearInterval(typingInterval);-->
<!--                        typingInterval = null;-->
<!--                    }-->

<!--                    scrollToBottom();-->
<!--                }-->
<!--            };-->

<!--            // 停止响应-->
<!--            const stopResponse = () => {-->
<!--                if (controller) {-->
<!--                    controller.abort();-->
<!--                    const lastMessage = messages.value[messages.value.length - 1];-->
<!--                    lastMessage.isLoading = false;-->
<!--                    lastMessage.isStreaming = false;-->

<!--                    if (lastMessage.visibleChars < lastMessage.content.length) {-->
<!--                        lastMessage.visibleChars = lastMessage.content.length;-->
<!--                    }-->

<!--                    isLoading.value = false;-->
<!--                    controller = null;-->

<!--                    if (typingInterval) {-->
<!--                        clearInterval(typingInterval);-->
<!--                        typingInterval = null;-->
<!--                    }-->
<!--                }-->
<!--            };-->

<!--            // 初始化-->
<!--            onMounted(async () => {-->
<!--                // 检查暗黑模式偏好-->
<!--                darkMode.value = localStorage.getItem('darkMode') === 'true' ||-->
<!--                    (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches);-->

<!--                welcomeText.value = await fetchWelcomeMessage();-->

<!--                // 添加欢迎消息-->
<!--                messages.value.push({-->
<!--                    role: 'assistant',-->
<!--                    content: welcomeText,-->
<!--                    isLoading: false,-->
<!--                    visibleChars: 0,-->
<!--                    isStreaming: false-->
<!--                });-->

<!--                // 确保欢迎消息完全可见-->
<!--                messages.value[0].visibleChars = messages.value[0].content.length;-->
<!--                scrollToBottom();-->

<!--                // 聚焦输入框-->
<!--                nextTick(() => {-->
<!--                    textarea.value.focus();-->
<!--                });-->
<!--            });-->

<!--            // 监听消息变化自动滚动-->
<!--            watch(messages, scrollToBottom, {deep: true});-->

<!--            return {-->
<!--                messages,-->
<!--                userInput,-->
<!--                isLoading,-->
<!--                darkMode,-->
<!--                chatContainer,-->
<!--                textarea,-->
<!--                sendMessage,-->
<!--                stopResponse,-->
<!--                toggleDarkMode,-->
<!--                fetchWelcomeMessage,-->
<!--                adjustTextareaHeight,-->
<!--                startNewConversation-->
<!--            };-->
<!--        }-->
<!--    }).mount('#app');-->
<!--</script>-->
<!--</body>-->
<!--</html>-->
